package sudoku.server.comunicaciones;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Hashtable;
import java.util.Vector;

import sudoku.client.comunicaciones.IJugador;
import sudoku.server.dominio.Kenken;
import sudoku.server.dominio.Sudoku;
import sudoku.server.persistencia.FachadaPersistencia;
import sudoku.server.persistencia.TableroDAO;
import sudoku.server.presen.JFServer;
import sudoku.server.dominio.Tablero;


@SuppressWarnings("serial")
public class Server extends UnicastRemoteObject implements IServer {

    private Hashtable<Integer, Tablero> cacheTableros;
	private JFServer ventana;

    public Server(JFServer ventana) throws RemoteException {
        super();
        this.ventana=ventana;
        LocateRegistry.createRegistry(2995);
        cacheTableros=new Hashtable<Integer, Tablero>();
    }

    public void poner(String id, byte idCuadricula, byte fila, byte columna, byte numero) throws RemoteException {
        Tablero tablero=this.findTablero(Integer.parseInt(id));
        if (tablero==null) 
        	return;
        tablero.poner(idCuadricula, fila, columna, numero);
    }

    public void quitar(String id, byte idCuadricula, byte fila, byte columna) throws RemoteException {
    	Tablero tablero=this.findTablero(Integer.parseInt(id));
        if (tablero==null) 
        	return;
        tablero.quitar(idCuadricula, fila, columna);
    }

    public void conectar(int tipoPersistencia, String ubicaciontableros) throws MalformedURLException, RemoteException {
        try {
            Naming.bind("rmi://127.0.0.1:2995/tableroserver", this);
           	FachadaPersistencia.buildInstancia(tipoPersistencia, ubicaciontableros);
        }
        catch (AlreadyBoundException ex) {
            Naming.rebind("rmi://127.0.0.1:2995/tableroserver", this);
            FachadaPersistencia.buildInstancia(tipoPersistencia, ubicaciontableros);
        }
    }

    public void desconectar() throws RemoteException, MalformedURLException, NotBoundException {
        Naming.unbind("rmi://127.0.0.1:2995/tableroserver");
    }

    public Vector<String> getTableros(int id) throws Exception {
    	
    	Vector <String> result = new Vector <String> ();
    	if (id%2==0){
	    	TableroDAO dao=FachadaPersistencia.getSudokuDAO();
	    	result=dao.getTableros("S");
    	}else{
    		TableroDAO dao = FachadaPersistencia.getKenkenDAO();
    		result=dao.getTableros("K");
    	}
    	return result;
    }

	public String getTablero(IJugador jugador, String idTablero, String idJugador) throws Exception {
		Tablero result=this.findTablero(Integer.parseInt(idTablero));
		if (result==null) {
			int idT = Integer.parseInt(idTablero);
			if (idT%2 == 0)
				result = new Sudoku(idTablero);
			else
				result = new Kenken(idTablero);
			this.putTablero(result);
		}
		if (result.findJugador(idJugador)!=null)
			throw new Exception("Ya hay un jugador con ese nombre en este tablero");
		result.add(jugador, idJugador);
		result.setVentana(this.ventana);
		
		return result.toString();
	}

	private void putTablero(Tablero result) {
		this.cacheTableros.put(result.getId(), result);
	}

	private Tablero findTablero(int id) {
		return (Tablero) this.cacheTableros.get(id);
	}

	public void guardarSudoku(String numeros) throws Exception {
		Tablero tablero = new Sudoku();
		tablero.setNumeros(numeros);
		tablero.insert();
	}
	
	public void guardarKenken(String numeros) throws Exception {
		Tablero tablero = new Kenken();
		tablero.setNumeros(numeros);
		tablero.insert();
	}
}
